package com.shuwen.gcdj.service.plan;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shuwen.gcdj.bean.DictResp;
import com.shuwen.gcdj.bean.VoidResp;
import com.shuwen.gcdj.bean.basicsEquitment.response.EquipmentResp;
import com.shuwen.gcdj.bean.plan.request.*;
import com.shuwen.gcdj.bean.plan.response.*;
import com.shuwen.gcdj.bean.strategy.request.AssociateDeviceReq;
import com.shuwen.gcdj.common.constant.Constants;
import com.shuwen.gcdj.common.exception.ApiException;
import com.shuwen.gcdj.common.util.BeanHelper;
import com.shuwen.gcdj.dto.account.InitUserDto;
import com.shuwen.gcdj.entity.*;
import com.shuwen.gcdj.entity.basics.BasicsEquipment;
import com.shuwen.gcdj.entity.basics.BasicsStrategy;
import com.shuwen.gcdj.mapper.mysql.*;
import com.shuwen.gcdj.service.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author :yys
 * @date : 2023/5/11 13:15
 */
@Service
@Slf4j
public class PlanService extends BaseService<PlanMapper, StrategyPlancycle> {

    @Autowired
    private PlanMapper planMapper;

    @Autowired
    private PlanDetailMapper planDetailMapper;

    @Autowired
    private BasicsStrategyMapper basicsStrategyMapper;

    @Autowired
    private StrategyEquipmentstrategyrelMapper strategyEquipmentstrategyrelMapper;

    @Autowired
    private BasicsStructureMapper basicsStructureMapper;

    @Autowired
    private StrategyInspectionitemtemplaterelMapper strategyInspectionitemtemplaterelMapper;

    private static String errorMessage = "保养计划类型异常";

    private static String time = " 00:00:00";

    /**
     * 获取计划明细分页信息
     *
     * @param req
     * @return
     */
    public Page<PlanDetailResp> getplandetailpagelist(PlanDetailPageReq req) {
        if (req == null || StringUtils.isEmpty(req.getMaintenanceType()) || StringUtils.isEmpty(req.getExecDate())) {
            throw new ApiException("类型和执行日期不能为空");
        }
        Page<PlanDetailResp> page = new Page<>(req.getPageNum(), req.getPageSize(), true);
        IPage<PlanDetailResp> allList = planMapper.getplandetailpagelist(page, req);
        List<PlanDetailResp> res = allList.getRecords();
        for (PlanDetailResp s : res) {
            List<ItemDetailResp> list = planMapper.getList(s.getStructureTempId(), s.getStructureId());
            s.setItemDetails(list);
            s.setItemCount(list.size());
        }
        Page<PlanDetailResp> resPage = new Page<>(page.getCurrent(), page.getSize(), allList.getTotal());
        resPage.setRecords(res);
        return resPage;

    }

    /**
     * 获取日历数据
     *
     * @param req
     * @return
     */
    public List<SecondPlanTreeResp> getThirdStructurePage(SecondPlanReq req) {
        //获取当前月第一天
        LocalDate localMonthDay = LocalDate.now().withDayOfMonth(1);
        //未传参数则默认获取当月数据
        if (StringUtils.isEmpty(req.getMonthDay())) {
            //适应日历控件扩展
            LocalDate startDate = localMonthDay.minusDays(7); //日期前移7天
            LocalDate endDate = localMonthDay.plusMonths(1).plusDays(7);//往后推移1月零7天
            req.setStartDate(startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            req.setEndDate(endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        } else {

            //适应日历控件扩展
            LocalDate startDate = LocalDate.parse(req.getMonthDay()).minusDays(7); //日期前移7天
            LocalDate endDate = LocalDate.parse(req.getMonthDay()).plusMonths(1).plusDays(7);//往后推移1月零7天
            req.setStartDate(startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            req.setEndDate(endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        List<SecondPlanTreeRespList> secondPlanTreeRespList = planMapper.getSecondPlanTreeRespList(req);
        List<SecondPlanTreeResp> secondPlanTreeResps = planMapper.getThirdStructurePage(req);
        for (SecondPlanTreeResp secondPlanTreeResp : secondPlanTreeResps) {
            List<ItemReq> itemReqs = new ArrayList<>();
            for (SecondPlanTreeRespList secondPlanTreeRespListItem : secondPlanTreeRespList) {
                if (secondPlanTreeResp.getDate().equals(secondPlanTreeRespListItem.getDate())) {
                    ItemReq itemReq = new ItemReq();
                    BeanUtil.copyProperties(secondPlanTreeRespListItem, itemReq);
                    itemReqs.add(itemReq);
                }
            }
            secondPlanTreeResp.setItemList(itemReqs);
        }
        return secondPlanTreeResps;
    }

    /**
     * 编辑一级保养计划状态
     *
     * @param req
     * @return
     */
    public VoidResp editfirstmaintainorderstate(InitUserDto initUserDto, EditFirstItemReq req) {
        if (req == null || StringUtils.isEmpty(req.getPlanDetailId())) {
            throw new ApiException("id不能为空");
        }
        StrategyPlandetail strategyPlandetail = planDetailMapper.selectById(req.getPlanDetailId());
        if (strategyPlandetail == null) {
            throw new ApiException("数据不存在");
        }
        if (strategyPlandetail.getState() == 3) {
            throw new ApiException("取消状态不可修改");
        }
        if (strategyPlandetail.getMaintenanceType() != 1) {
            throw new ApiException(errorMessage);
        }
        strategyPlandetail.setUpdateTime(null);
        strategyPlandetail.setState(3);
        strategyPlandetail.setUpdateId(initUserDto.getUserId());
        planDetailMapper.updateById(strategyPlandetail);
        return new VoidResp();
    }

    /**
     * 一键关闭
     *
     * @param initUser
     * @param req
     * @return
     */
    public VoidResp closeallfirstmain(InitUserDto initUser, CloseAllFirstMainReq req) {
        if (req == null || StringUtils.isEmpty(req.getExecDate())) {
            throw new ApiException("执行日期不能为空");
        }
        LambdaQueryWrapper<StrategyPlandetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StrategyPlandetail::getExecDate, req.getExecDate())
                .eq(StrategyPlandetail::getMaintenanceType, Constants.MAJOR_JI);
        List<StrategyPlandetail> strategyPlandetails = planDetailMapper.selectList(queryWrapper);
        for (StrategyPlandetail s : strategyPlandetails) {
            if (s.getState() == 3) {
                continue;
            }
            if (s.getMaintenanceType() != 1) {
                throw new ApiException(errorMessage);
            }
            s.setUpdateId(initUser.getUserId());
            s.setUpdateTime(null);
            s.setState(3);
            planDetailMapper.updateById(s);
        }
        return new VoidResp();
    }

    /**
     * 一键修改日期
     *
     * @param initUser
     * @param req
     * @return
     */
    public VoidResp editallsecondmaintainorderstatebydate(InitUserDto initUser, EditallSecondReq req) {
        if (req == null || StringUtils.isEmpty(req.getExecDate()) || StringUtils.isEmpty(req.getTargetDate())) {
            throw new ApiException("必填参数不完整！");
        }
        String str = "变更至" + req.getTargetDate() + time;
        LambdaQueryWrapper<StrategyPlandetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StrategyPlandetail::getExecDate, req.getExecDate())
                .eq(StrategyPlandetail::getMaintenanceType, Constants.MAJOR_DIAN);
        List<StrategyPlandetail> strategyPlandetails = planDetailMapper.selectList(queryWrapper);
        for (StrategyPlandetail s : strategyPlandetails) {
            if (s.getState() == 3) {
                continue;
            }
            if (s.getMaintenanceType() != 2) {
                throw new ApiException(errorMessage);
            }
            //        copy一份（修改执行日期）
            StrategyPlandetail strategyPlandetailOne = planDetailMapper.selectById(s.getId());
            strategyPlandetailOne.setId(null);
            strategyPlandetailOne.setRemark("原日期" + strategyPlandetailOne.getExecDate());
            strategyPlandetailOne.setExecDate(req.getTargetDate() + time);
            strategyPlandetailOne.setUpdateTime(null);
            strategyPlandetailOne.setState(2);
            strategyPlandetailOne.setUpdateId(initUser.getUserId());
            planDetailMapper.insert(strategyPlandetailOne);
//            需要在查一边
            s = planDetailMapper.selectById(s.getId());
            s.setUpdateId(initUser.getUserId());
            s.setUpdateTime(null);
            s.setRemark(str);
            s.setState(3);
            planDetailMapper.updateById(s);
        }
        return new VoidResp();
    }

    /**
     * 编辑二级保养计划日期
     *
     * @param initUser
     * @param req
     * @return
     */
    public VoidResp editsecondmaintainorderstate(InitUserDto initUser, EditSecondItemReq req) {
        if (req == null || StringUtils.isEmpty(req.getPlanDetailId()) || StringUtils.isEmpty(req.getTargetDate())) {
            throw new ApiException("必填参数不完整！");
        }
        String str = "变更至" + req.getTargetDate() + time;
        StrategyPlandetail strategyPlandetail = planDetailMapper.selectById(req.getPlanDetailId());
        if (strategyPlandetail == null) {
            throw new ApiException("数据不存在");
        }
        if (strategyPlandetail.getState() == 3) {
            throw new ApiException("取消状态不可修改");
        }
        if (strategyPlandetail.getMaintenanceType() != 2) {
            throw new ApiException(errorMessage);
        }
//        copy一份（修改执行日期）
        StrategyPlandetail strategyPlandetailOne = planDetailMapper.selectById(req.getPlanDetailId());
        strategyPlandetailOne.setId(null);
        strategyPlandetailOne.setRemark("原日期" + strategyPlandetailOne.getExecDate());
        strategyPlandetailOne.setExecDate(req.getTargetDate() + time);
        strategyPlandetailOne.setCreateTime(null);
        strategyPlandetailOne.setUpdateTime(null);
        strategyPlandetailOne.setState(2);
        strategyPlandetailOne.setCreateId(initUser.getUserId());
        strategyPlandetailOne.setUpdateId(initUser.getUserId());
        planDetailMapper.insert(strategyPlandetailOne);
//        修改状态
        strategyPlandetail = planDetailMapper.selectById(req.getPlanDetailId());
        strategyPlandetail.setRemark(str);
        strategyPlandetail.setState(3);
        strategyPlandetail.setUpdateTime(null);
        strategyPlandetail.setUpdateId(initUser.getUserId());
        planDetailMapper.updateById(strategyPlandetail);
        return new VoidResp();
    }

    /**
     * 获取上一次计划生成执行的结束日期
     *
     * @return
     */
    public String getmaxexecdatebystrategyid(String equipmentId) {
        //过滤设备和设备状态是正常(1)的计划明细
        LambdaQueryWrapper<StrategyPlandetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StrategyPlandetail::getIsDelete, Constants.IS_DELETE_NORMAL)
                .eq(StrategyPlandetail::getEquipmentId, equipmentId)
                .eq(StrategyPlandetail::getState, 1)
                .orderByDesc(StrategyPlandetail::getExecDate)
                .last("limit 1");
        StrategyPlandetail strategyPlandetail = planDetailMapper.selectOne(queryWrapper);
        if (strategyPlandetail == null) {
            return null;
        }
        return strategyPlandetail.getExecDate();
    }

    /**
     * 生成计划明细
     *
     * @param initUser
     * @param req
     * @return
     */
    public VoidResp createmaintainplandetail(InitUserDto initUser, CreateMaintainPlanReq req) throws ParseException {
        if (req == null || StringUtils.isEmpty(req.getEndDate()) || StringUtils.isEmpty(req.getStartDate()) || StringUtils.isEmpty(req.getEquipmentId())) {
            throw new ApiException("必填参数不完整");
        }
        //按天算时间段总数
        List<String> dateList = getDateList(req.getStartDate(), req.getEndDate());
        //获取开启的策略
        List<BasicsStrategy> basicsStrategies = basicsStrategyMapper.selectList(new QueryWrapper<BasicsStrategy>()
                .lambda()
                .eq(BasicsStrategy::getState, Constants.IS_ACTIVE_TEM)
                .eq(BasicsStrategy::getIsDelete, Constants.IS_DELETE_NORMAL)
        );
        //判断没有开启策略直接返回
        if (CollectionUtils.isEmpty(basicsStrategies)) {
            return new VoidResp();
        }
        List<String> strategyIds = basicsStrategies.stream().map(s -> s.getId()).collect(Collectors.toList());
        //查询开启策略的设备关联信息并过滤指定的设备信息
        List<StrategyEquipmentstrategyrel> strategyEquipmentstrategyrelList = strategyEquipmentstrategyrelMapper.selectList(new QueryWrapper<StrategyEquipmentstrategyrel>()
                .lambda()
                .in(StrategyEquipmentstrategyrel::getStrategyId, strategyIds)
                .eq(StrategyEquipmentstrategyrel::getEquipmentId, req.getEquipmentId())
                .eq(StrategyEquipmentstrategyrel::getIsDelete, Constants.IS_DELETE_NORMAL)
        );
        //过滤没绑定设备的策略
        Iterator<BasicsStrategy> iterator = basicsStrategies.iterator();
        while (iterator.hasNext()) {
            List<StrategyEquipmentstrategyrel> sLsit = strategyEquipmentstrategyrelList.stream().filter(ser -> ser.getStrategyId().equals(iterator.next().getId())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(sLsit)) {
                iterator.remove();
            }
        }
        //获取相关计划信息
        List<StrategyPlancycle> strategyPlancycleList = planMapper.selectList(new QueryWrapper<StrategyPlancycle>()
                .lambda()
                .in(StrategyPlancycle::getStrategyId, strategyIds)
                .eq(StrategyPlancycle::getIsDelete, Constants.IS_DELETE_NORMAL)
        );
        //判断没有计划信息直接返回
        if (CollectionUtils.isEmpty(strategyPlancycleList)) {
            return new VoidResp();
        }
        List<String> firstStructureIds = strategyPlancycleList.stream().map(sp -> sp.getStructureId()).collect(Collectors.toList());
        //获取计划相关的二级结构
        List<BasicsStructure> secondStructureList = basicsStructureMapper.selectList(new QueryWrapper<BasicsStructure>()
                .lambda()
                .in(BasicsStructure::getParentId, firstStructureIds)
                .eq(BasicsStructure::getIsDelete, Constants.IS_DELETE_NORMAL)
        );
        //判断没有二级结构信息直接返回
        if (CollectionUtils.isEmpty(secondStructureList)) {
            return new VoidResp();
        }
        List<String> secondStructureIds = secondStructureList.stream().map(sp -> sp.getId()).collect(Collectors.toList());
        //获取相关检查项关联信息并根据模板Id分组去重
        List<StrategyInspectionitemtemplaterel> strategyInspectionitemtemplaterelList = strategyInspectionitemtemplaterelMapper.selectList(new QueryWrapper<StrategyInspectionitemtemplaterel>()
                .lambda()
                .in(StrategyInspectionitemtemplaterel::getStructureId, secondStructureIds)
                .eq(StrategyInspectionitemtemplaterel::getIsDelete, Constants.IS_DELETE_NORMAL)
                .groupBy(StrategyInspectionitemtemplaterel::getTemplateId,StrategyInspectionitemtemplaterel::getStructureId)
        );
        //需要生成的计划明细信息
        List<StrategyPlandetail> addStrategyPlandetailList = new ArrayList<>();
        //找策略下面的所有一级保养计划
        for (BasicsStrategy bs : basicsStrategies) {
            //设备
            List<StrategyEquipmentstrategyrel> sLsit = strategyEquipmentstrategyrelList.stream().filter(ser -> ser.getStrategyId().equals(bs.getId())).collect(Collectors.toList());
            for (StrategyEquipmentstrategyrel sl : sLsit) {
                List<StrategyPlancycle> strategyPlancycles = strategyPlancycleList.stream().filter(sp -> sp.getStrategyId().equals(bs.getId()) && sp.getMaintenanceType().equals(1)).collect(Collectors.toList());
                //二级
                for (StrategyPlancycle sp : strategyPlancycles) {
                    List<BasicsStructure> basicsStructures = secondStructureList.stream().filter(second -> second.getParentId().equals(sp.getStructureId())).collect(Collectors.toList());
                    for (BasicsStructure bbs : basicsStructures) {
                        //三级模板
                        List<StrategyInspectionitemtemplaterel> siList = strategyInspectionitemtemplaterelList.stream().filter(siit -> siit.getStructureId().equals(bbs.getId())).collect(Collectors.toList());
                        for (StrategyInspectionitemtemplaterel si : siList) {
                            //时间范围
                            for (String s : dateList) {
                                addStrategyPlandetailList.add(createPlanDetail(initUser, s, sp, sl, si, bbs, Constants.MEI));
                            }
                        }

                    }

                }


            }

        }
        //找策略下面的所有二级保养计划
        for (BasicsStrategy bs : basicsStrategies) {
            List<StrategyEquipmentstrategyrel> sLsit = strategyEquipmentstrategyrelList.stream().filter(ser -> ser.getStrategyId().equals(bs.getId())).collect(Collectors.toList());
            for (StrategyEquipmentstrategyrel sl : sLsit) {
                //二级保养
                List<StrategyPlancycle> strategyPlancycles = strategyPlancycleList.stream().filter(sp -> sp.getStrategyId().equals(bs.getId()) && sp.getMaintenanceType().equals(2)).collect(Collectors.toList());

                for (StrategyPlancycle sp : strategyPlancycles) {
                    List<BasicsStructure> basicsStructures = secondStructureList.stream().filter(second -> second.getParentId().equals(sp.getStructureId())).collect(Collectors.toList());
                    for (BasicsStructure bbs : basicsStructures) {
                        //三级模板
                        List<StrategyInspectionitemtemplaterel> siList = strategyInspectionitemtemplaterelList.stream().filter(siit -> siit.getStructureId().equals(bbs.getId())).collect(Collectors.toList());
                        for (StrategyInspectionitemtemplaterel si : siList) {
                            //时间处理
                            //周
                            Calendar c = Calendar.getInstance();
                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                            if (!StringUtils.isEmpty(sp.getWeekly())) {
                                for (String s : dateList) {
                                    c.setTime(simpleDateFormat.parse(s));
                                    String weekday = c.get(Calendar.DAY_OF_WEEK) + "";
                                    if (sp.getWeekly().contains(weekday)) {
                                        addStrategyPlandetailList.add(createPlanDetail(initUser, s, sp, sl, si, bbs, Constants.WEEKLY));
                                    }

                                }
                            }
                            //月
                            if (!StringUtils.isEmpty(sp.getMonthly())) {
                                for (String s : dateList) {
                                    c.setTime(simpleDateFormat.parse(s));
                                    String weekday = c.get(Calendar.DAY_OF_MONTH) + "";
                                    if (sp.getMonthly().contains(weekday)) {
                                        addStrategyPlandetailList.add(createPlanDetail(initUser, s, sp, sl, si, bbs, Constants.MONTHLY));
                                    }

                                }
                            }
                            //季
                            if (!StringUtils.isEmpty(sp.getSeason())) {
                                for (String s : dateList) {
                                    if (sp.getSeason().contains(getDateStr(s))) {
                                        addStrategyPlandetailList.add(createPlanDetail(initUser, s, sp, sl, si, bbs, Constants.SEASON));
                                    }

                                }
                            }
                            //年
                            if (!StringUtils.isEmpty(sp.getYearly())) {
                                for (String s : dateList) {
                                    if (sp.getYearly().contains(getDateStr(s))) {
                                        addStrategyPlandetailList.add(createPlanDetail(initUser, s, sp, sl, si, bbs, Constants.YEARLY));
                                    }

                                }
                            }
                            //自定义天
                            if (!StringUtils.isEmpty(sp.getCustomerDay())) {
                                for (String s : dateList) {
                                    if (sp.getCustomerDay().contains(getDateStr(s))) {
                                        addStrategyPlandetailList.add(createPlanDetail(initUser, s, sp, sl, si, bbs, Constants.CUSTOMER_DAY));
                                    }

                                }
                            }
                            //隔天执行
                            if (!StringUtils.isEmpty(sp.getEveryDay())) {
                                int i = 0;
                                for (String s : dateList) {

                                    if (i == 0) {
                                        addStrategyPlandetailList.add(createPlanDetail(initUser, s, sp, sl, si, bbs, Constants.EVERY_DAY));
                                        i++;
                                        continue;
                                    }
                                    if (i == sp.getEveryDay() + 1) {
                                        addStrategyPlandetailList.add(createPlanDetail(initUser, s, sp, sl, si, bbs, Constants.EVERY_DAY));
                                        i = 1;
                                    } else {
                                        i++;
                                    }

                                }
                            }
                        }

                    }

                }

            }

        }
        if(CollectionUtils.isEmpty(addStrategyPlandetailList))
        {
            return new VoidResp();
        }
        //综合向数据库进行插入避免循环插入对性能造成影响
        if (addStrategyPlandetailList.size() <= 1000) {
            planDetailMapper.insertBatch(addStrategyPlandetailList);
        } else {
            int totallCount = addStrategyPlandetailList.size();
            int pages = BeanHelper.getCeiling(totallCount, 1000);
            for (int i = 1; i <= pages; i++) {
                List<StrategyPlandetail> thisbatch = addStrategyPlandetailList.stream().skip((i - 1) * 1000L).limit(1000).collect(Collectors.toList());
                planDetailMapper.insertBatch(thisbatch);
            }
        }
        return new VoidResp();
    }

    /**
     * 生成计划明细(策略关联设备)
     * @param initUser
     * @param req
     * @return
     */
    public VoidResp createmaintainplandetailByStrategy(InitUserDto initUser, CreateMaintainPlanReq req, AssociateDeviceReq deviceReq) throws ParseException {
        if (req == null || StringUtils.isEmpty(req.getEndDate()) || StringUtils.isEmpty(req.getStartDate()) || StringUtils.isEmpty(req.getEquipmentId())) {
            throw new ApiException("必填参数不完整");
        }
        //按天算时间段总数
        List<String> dateList = getDateList(req.getStartDate(), req.getEndDate());
        //开启的策略
        BasicsStrategy basicsStrategies = basicsStrategyMapper.selectOne(new QueryWrapper<BasicsStrategy>()
                .lambda()
                .eq(BasicsStrategy::getState, Constants.IS_ACTIVE_TEM)
                .eq(BasicsStrategy::getIsDelete, Constants.IS_DELETE_NORMAL)
                .eq(BasicsStrategy::getId, deviceReq.getStrategyId())
        );
        //未开启策略，不生成计划详情
        if (basicsStrategies == null) {
            return new VoidResp();
        }
        //未绑定设备,不生成计划详情
        List<StrategyEquipmentstrategyrel> sLsit = strategyEquipmentstrategyrelMapper.selectList(new QueryWrapper<StrategyEquipmentstrategyrel>()
                .lambda()
                .eq(StrategyEquipmentstrategyrel::getStrategyId, basicsStrategies.getId())
                .eq(StrategyEquipmentstrategyrel::getEquipmentId, deviceReq.getEquipmentId())
                .eq(StrategyEquipmentstrategyrel::getIsDelete, Constants.IS_DELETE_NORMAL)
        );
        if (CollectionUtils.isEmpty(sLsit)) {
            return new VoidResp();
        }
        //获取相关计划信息
        List<StrategyPlancycle> strategyPlancycleList = planMapper.selectList(new QueryWrapper<StrategyPlancycle>()
                .lambda()
                .eq(StrategyPlancycle::getStrategyId, basicsStrategies.getId())
                .eq(StrategyPlancycle::getIsDelete, Constants.IS_DELETE_NORMAL)
        );
        //判断没有计划信息直接返回
        if (CollectionUtils.isEmpty(strategyPlancycleList)) {
            return new VoidResp();
        }
        List<String> firstStructureIds = strategyPlancycleList.stream().map(sp -> sp.getStructureId()).collect(Collectors.toList());
        //获取计划相关的二级结构
        List<BasicsStructure> secondStructureList = basicsStructureMapper.selectList(new QueryWrapper<BasicsStructure>()
                .lambda()
                .in(BasicsStructure::getParentId, firstStructureIds)
                .eq(BasicsStructure::getIsDelete, Constants.IS_DELETE_NORMAL)
        );
        //判断没有二级结构信息直接返回
        if (CollectionUtils.isEmpty(secondStructureList)) {
            return new VoidResp();
        }
        List<String> secondStructureIds = secondStructureList.stream().map(sp -> sp.getId()).collect(Collectors.toList());
        //获取相关检查项关联信息并根据模板Id分组去重
        List<StrategyInspectionitemtemplaterel> strategyInspectionitemtemplaterelList = strategyInspectionitemtemplaterelMapper.selectList(new QueryWrapper<StrategyInspectionitemtemplaterel>()
                .lambda()
                .in(StrategyInspectionitemtemplaterel::getStructureId, secondStructureIds)
                .eq(StrategyInspectionitemtemplaterel::getIsDelete, Constants.IS_DELETE_NORMAL)
                .groupBy(StrategyInspectionitemtemplaterel::getTemplateId,StrategyInspectionitemtemplaterel::getStructureId)
        );
        //需要生成的计划明细信息
        List<StrategyPlandetail> addStrategyPlandetailList = new ArrayList<>();

        //找策略下面的所有一级保养计划
        List<StrategyPlancycle> strategyPlancycles = strategyPlancycleList.stream().filter(sp->sp.getStrategyId().equals(deviceReq.getStrategyId()) && sp.getMaintenanceType().equals(1)).collect(Collectors.toList());
        for (StrategyPlancycle sp : strategyPlancycles) {
            List<BasicsStructure> basicsStructures = secondStructureList.stream().filter(second -> second.getParentId().equals(sp.getStructureId())).collect(Collectors.toList());
            for (BasicsStructure bbs : basicsStructures) {
                //三级模板
                List<StrategyInspectionitemtemplaterel> siList = strategyInspectionitemtemplaterelList.stream().filter(siit -> siit.getStructureId().equals(bbs.getId())).collect(Collectors.toList());
                for (StrategyInspectionitemtemplaterel si : siList) {
                    //时间范围
                    for (String s : dateList) {
                        addStrategyPlandetailList.add(createPlanDetailByStrategy(initUser, s, sp, deviceReq.getEquipmentId(), si, bbs, Constants.MEI));
                    }
                }

            }

        }
        //找策略下面的所有二级保养计划
        List<StrategyPlancycle> secondStrategyPlancycleList = strategyPlancycleList.stream().filter(sp->sp.getStrategyId().equals(deviceReq.getStrategyId()) && sp.getMaintenanceType().equals(2)).collect(Collectors.toList());
        for (StrategyPlancycle sp : secondStrategyPlancycleList) {
            List<BasicsStructure> basicsStructures = secondStructureList.stream().filter(second -> second.getParentId().equals(sp.getStructureId())).collect(Collectors.toList());
            for (BasicsStructure bbs : basicsStructures) {
                //三级模板
                List<StrategyInspectionitemtemplaterel> siList = strategyInspectionitemtemplaterelList.stream().filter(siit -> siit.getStructureId().equals(bbs.getId())).collect(Collectors.toList());
                for (StrategyInspectionitemtemplaterel si : siList) {
                    //时间处理
                    //周
                    Calendar c = Calendar.getInstance();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    if (!StringUtils.isEmpty(sp.getWeekly())) {
                        for (String s : dateList) {
                            c.setTime(simpleDateFormat.parse(s));
                            String weekday = c.get(Calendar.DAY_OF_WEEK) + "";
                            if (sp.getWeekly().contains(weekday)) {
                                addStrategyPlandetailList.add(createPlanDetailByStrategy(initUser, s, sp, deviceReq.getEquipmentId(), si, bbs, Constants.WEEKLY));
                            }

                        }
                    }
                    //月
                    if (!StringUtils.isEmpty(sp.getMonthly())) {
                        for (String s : dateList) {
                            c.setTime(simpleDateFormat.parse(s));
                            String weekday = c.get(Calendar.DAY_OF_MONTH) + "";
                            if (sp.getMonthly().contains(weekday)) {
                                addStrategyPlandetailList.add(createPlanDetailByStrategy(initUser, s, sp, deviceReq.getEquipmentId(), si, bbs, Constants.MONTHLY));
                            }

                        }
                    }
                    //季
                    if (!StringUtils.isEmpty(sp.getSeason())) {
                        for (String s : dateList) {
                            if (sp.getSeason().contains(getDateStr(s))) {
                                addStrategyPlandetailList.add(createPlanDetailByStrategy(initUser, s, sp, deviceReq.getEquipmentId(), si, bbs, Constants.SEASON));
                            }

                        }
                    }
                    //年
                    if (!StringUtils.isEmpty(sp.getYearly())) {
                        for (String s : dateList) {
                            if (sp.getYearly().contains(getDateStr(s))) {
                                addStrategyPlandetailList.add(createPlanDetailByStrategy(initUser, s, sp, deviceReq.getEquipmentId(), si, bbs, Constants.YEARLY));
                            }

                        }
                    }
                    //自定义天
                    if (!StringUtils.isEmpty(sp.getCustomerDay())) {
                        for (String s : dateList) {
                            if (sp.getCustomerDay().contains(getDateStr(s))) {
                                addStrategyPlandetailList.add(createPlanDetailByStrategy(initUser, s, sp, deviceReq.getEquipmentId(), si, bbs, Constants.CUSTOMER_DAY));
                            }

                        }
                    }
                    //隔天执行
                    if (!StringUtils.isEmpty(sp.getEveryDay())) {
                        int i = 0;
                        for (String s : dateList) {

                            if (i == 0) {
                                addStrategyPlandetailList.add(createPlanDetailByStrategy(initUser, s, sp, deviceReq.getEquipmentId(), si, bbs, Constants.EVERY_DAY));
                                i++;
                                continue;
                            }
                            if (i == sp.getEveryDay() + 1) {
                                addStrategyPlandetailList.add(createPlanDetailByStrategy(initUser, s, sp, deviceReq.getEquipmentId(), si, bbs, Constants.EVERY_DAY));
                                i = 1;
                            } else {
                                i++;
                            }

                        }
                    }
                }

            }

        }
        if(CollectionUtils.isEmpty(addStrategyPlandetailList))
        {
            return new VoidResp();
        }
        //综合向数据库进行插入避免循环插入对性能造成影响
        if (addStrategyPlandetailList.size() <= 1000) {
            planDetailMapper.insertBatch(addStrategyPlandetailList);
        } else {
            int totallCount = addStrategyPlandetailList.size();
            int pages = BeanHelper.getCeiling(totallCount, 1000);
            for (int i = 1; i <= pages; i++) {
                List<StrategyPlandetail> thisbatch = addStrategyPlandetailList.stream().skip((i - 1) * 1000L).limit(1000).collect(Collectors.toList());
                planDetailMapper.insertBatch(thisbatch);
            }
        }
        return new VoidResp();
    }

    /**
     * 生成计划详情
     *
     * @param initUser 用户信息
     * @param s        执行时间
     * @param sp       计划
     * @param sl       设备策略中间表
     * @param si       检查项模板中间表
     * @param bbs      部件表
     */
    public StrategyPlandetail createPlanDetail(InitUserDto initUser,
                                               String s,
                                               StrategyPlancycle sp,
                                               StrategyEquipmentstrategyrel sl,
                                               StrategyInspectionitemtemplaterel si,
                                               BasicsStructure bbs,
                                               Integer planCycleType) {
        StrategyPlandetail strategyPlandetail = new StrategyPlandetail();
        strategyPlandetail.setCreateId(initUser.getUserId());
        strategyPlandetail.setUpdateId(initUser.getUserId());
        strategyPlandetail.setExecDate(s);
        strategyPlandetail.setPlanCycleType(planCycleType);
        strategyPlandetail.setStrategyId(sp.getStrategyId());
        strategyPlandetail.setMaintenanceType(sp.getMaintenanceType());
        strategyPlandetail.setPlancycleId(sp.getId());
        strategyPlandetail.setEquipmentId(sl.getEquipmentId());
        strategyPlandetail.setFirstStructureId(sp.getStructureId());
        strategyPlandetail.setItemTempId(si.getTemplateId());
        strategyPlandetail.setSecondStructureId(si.getStructureId());
        strategyPlandetail.setMajor(bbs.getStructureType());
        strategyPlandetail.setUserId(bbs.getPersonnelId());
        //planDetailMapper.insert(strategyPlandetail);
        return strategyPlandetail;
    }

    /**
     * 生成计划详情
     *
     * @param initUser 用户信息
     * @param s        执行时间
     * @param sp       计划
     * @param sl       设备策略中间表
     * @param si       检查项模板中间表
     * @param bbs      部件表
     */
    public StrategyPlandetail createPlanDetailByStrategy(InitUserDto initUser,
                                                         String s,
                                                         StrategyPlancycle sp,
                                                         String sl,
                                                         StrategyInspectionitemtemplaterel si,
                                                         BasicsStructure bbs,
                                                         Integer planCycleType) {
        StrategyPlandetail strategyPlandetail = new StrategyPlandetail();
        strategyPlandetail.setCreateId(initUser.getUserId());
        strategyPlandetail.setUpdateId(initUser.getUserId());
        strategyPlandetail.setPlanCycleType(planCycleType);
        strategyPlandetail.setExecDate(s);
        strategyPlandetail.setStrategyId(sp.getStrategyId());
        strategyPlandetail.setMaintenanceType(sp.getMaintenanceType());
        strategyPlandetail.setPlancycleId(sp.getId());
        strategyPlandetail.setEquipmentId(sl);
        strategyPlandetail.setFirstStructureId(sp.getStructureId());
        strategyPlandetail.setItemTempId(si.getTemplateId());
        strategyPlandetail.setSecondStructureId(si.getStructureId());
        strategyPlandetail.setMajor(bbs.getStructureType());
        strategyPlandetail.setUserId(bbs.getPersonnelId());
        //planDetailMapper.insert(strategyPlandetail);
        return  strategyPlandetail;
    }

    /**
     * 当日计划统计
     *
     * @param req
     * @return
     */
    public List<SecondPlanTreeResp> getCureDatePlan(PlanIndexReq req) {
        if (req == null || StringUtils.isEmpty(req.getStartDate()) || StringUtils.isEmpty(req.getEndDate())) {
            throw new ApiException("必填项不能为空");
        }
        List<SecondPlanTreeResp> cureDatePlan = planMapper.getCureDatePlan(req);
        List<SecondPlanTreeRespList> secondPlanTreeRespList = planMapper.getCureDatePlanList(req);
        for (SecondPlanTreeResp secondPlanTreeResp : cureDatePlan) {
            List<ItemReq> itemReqs = new ArrayList<>();
            for (SecondPlanTreeRespList secondPlanTreeRespListItem : secondPlanTreeRespList) {
                if (secondPlanTreeResp.getDate().equals(secondPlanTreeRespListItem.getDate())) {
                    ItemReq itemReq = new ItemReq();
                    BeanUtil.copyProperties(secondPlanTreeRespListItem, itemReq);
                    itemReqs.add(itemReq);
                }
            }
            secondPlanTreeResp.setItemList(itemReqs);
        }
        return cureDatePlan;
    }

    /**
     * 获取设备信息
     *
     * @param equipmentId
     * @return
     */
    public EquipmentResp getequipmentbyid(String equipmentId) {
        LambdaQueryWrapper<BasicsEquipment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BasicsEquipment::getIsDelete, Constants.IS_DELETE_NORMAL)
                .eq(BasicsEquipment::getId, equipmentId);
        BasicsEquipment basicsEquipment = new BasicsEquipment();
        BasicsEquipment basicsEquipments = basicsEquipment.selectOne(queryWrapper);

        Account account = new Account();
        Account accountOne = account.selectOne(new LambdaQueryWrapper<Account>().eq(Account::getIsDelete, Constants.IS_DELETE_NORMAL)
                .eq(Account::getId, basicsEquipments.getManager()));
        EquipmentResp equipmentResp = new EquipmentResp();
        if (!StringUtils.isEmpty(basicsEquipments.getName())) {
            equipmentResp.setName(basicsEquipments.getName());
        }
        if (accountOne != null) {
            equipmentResp.setManager(accountOne.getShowName());
        }
        return equipmentResp;
    }

    /**
     * 获取设备编号
     *
     * @return
     */
    public List<DictResp> getstructuretypecode() {
        LambdaQueryWrapper<BasicsEquipment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BasicsEquipment::getIsDelete, Constants.IS_DELETE_NORMAL);
        queryWrapper.orderByAsc(BasicsEquipment::getCreateTime);
        BasicsEquipment basicsEquipment = new BasicsEquipment();
        List<BasicsEquipment> basicsEquipments = basicsEquipment.selectList(queryWrapper);
        List<DictResp> list = new ArrayList<>();
        for (BasicsEquipment bs : basicsEquipments) {
            DictResp dictResp = new DictResp();
            dictResp.setValue(bs.getId());
            dictResp.setName(bs.getName());
            list.add(dictResp);
        }
        return list;
    }

    /**
     * 获取计划周期
     *
     * @return
     */
    public List<DictResp> getstructuretypeqi() {
        LambdaQueryWrapper<SysDictionary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDictionary::getParentCode, Constants.STRATEGY_PLAN_DETAIL_PLAN_CYCLETYPE)
                .eq(SysDictionary::getState, Constants.IS_ACTIVE_TEM)
                .eq(SysDictionary::getIsDelete, Constants.IS_DELETE_NORMAL);
        SysDictionary sysDictionary = new SysDictionary();
        List<SysDictionary> sysDictionaries = sysDictionary.selectList(queryWrapper);
        return BeanHelper.copyList(sysDictionaries, DictResp.class);
    }

    /**
     * 获取计划状态
     *
     * @return
     */
    public List<DictResp> getplanstate() {
        LambdaQueryWrapper<SysDictionary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDictionary::getParentCode, Constants.STRATEGY_PLAN_DETAIL_STATE)
                .eq(SysDictionary::getState, Constants.IS_ACTIVE_TEM)
                .eq(SysDictionary::getIsDelete, Constants.IS_DELETE_NORMAL);
        SysDictionary sysDictionary = new SysDictionary();
        List<SysDictionary> sysDictionaries = sysDictionary.selectList(queryWrapper);
        return BeanHelper.copyList(sysDictionaries, DictResp.class);
    }

    /**
     * 分派人员
     *
     * @param equipmentId
     * @return
     */
    public List<DictResp> getplanper(String equipmentId) {
        //        通过设备id获取策略id
        LambdaQueryWrapper<StrategyEquipmentstrategyrel> queryWrapperOne = new LambdaQueryWrapper<>();
        queryWrapperOne.eq(StrategyEquipmentstrategyrel::getEquipmentId, equipmentId)
                .eq(StrategyEquipmentstrategyrel::getIsDelete, Constants.IS_DELETE_NORMAL);
        StrategyEquipmentstrategyrel strategyEquipmentstrategyrel = new StrategyEquipmentstrategyrel();
        List<StrategyEquipmentstrategyrel> strategyEquipmentstrategyrels = strategyEquipmentstrategyrel.selectList(queryWrapperOne);
        List<DictResp> list = new ArrayList<>();
        for (StrategyEquipmentstrategyrel s : strategyEquipmentstrategyrels) {
//            根据策略id获取用户id
            LambdaQueryWrapper<BasicsStructure> queryWrapperTwo = new LambdaQueryWrapper<>();
            queryWrapperTwo.eq(BasicsStructure::getStrategyId, s.getStrategyId())
                    .eq(BasicsStructure::getIsDelete, Constants.IS_DELETE_NORMAL)
                    .groupBy(BasicsStructure::getPersonnelId);
            BasicsStructure basicsStructure = new BasicsStructure();
            List<BasicsStructure> basicsStructureList = basicsStructure.selectList(queryWrapperTwo);
            if (CollectionUtils.isEmpty(basicsStructureList)) {
                continue;
            }
//             获取分派人员
            for (BasicsStructure b : basicsStructureList) {
                LambdaQueryWrapper<Account> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Account::getIsDelete, Constants.IS_DELETE_NORMAL)
                        .eq(Account::getId, b.getPersonnelId());
                Account account = new Account();
                Account accountById = account.selectOne(queryWrapper);
                if (accountById == null) {
                    continue;
                }
                DictResp dictResp = new DictResp();
                dictResp.setValue(accountById.getId());
                dictResp.setName(accountById.getShowName());
                list.add(dictResp);
            }
        }
        return list;
    }

    /**
     * 计划类型
     *
     * @return
     */
    public List<DictResp> getplantype() {
        LambdaQueryWrapper<SysDictionary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDictionary::getParentCode, Constants.BASICS_STRUCTURE_TYPE)
                .eq(SysDictionary::getState, Constants.IS_ACTIVE_TEM)
                .eq(SysDictionary::getIsDelete, Constants.IS_DELETE_NORMAL);
        SysDictionary sysDictionary = new SysDictionary();
        List<SysDictionary> sysDictionaries = sysDictionary.selectList(queryWrapper);
        return BeanHelper.copyList(sysDictionaries, DictResp.class);
    }
}
